package com.kexilo.core.security.service;

import com.kexilo.core.common.exception.ServiceException;
import com.kexilo.core.common.utils.StringUtils;
import com.kexilo.core.security.domain.LoginUser;
import com.kexilo.core.security.dto.UserDTO;
import com.kexilo.core.security.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;

/**
 * 用户验证处理
 * 
 * @author Kexilo
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    
    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    
    @Autowired(required = false)
    private IUserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StringUtils.isEmpty(username)) {
            log.info("登录用户：{} 不存在.", username);
            throw new UsernameNotFoundException("登录用户：" + username + " 不存在");
        }
        
        // 检查用户服务是否可用
        if (userService == null) {
            log.error("用户服务未实现，无法进行用户认证");
            throw new UsernameNotFoundException("用户认证服务未可用，请联系管理员");
        }
        
        try {
            // 从数据库查询用户信息
            UserDTO user = userService.selectUserDTOByUserName(username);
            if (user == null) {
                log.info("登录用户：{} 不存在.", username);
                throw new UsernameNotFoundException("登录用户：" + username + " 不存在");
            }
            
            // 验证用户状态
            validateUserStatus(user);
            
            // 获取用户权限
            Set<String> permissions = userService.getUserPermissions(user.getUserId());
            
            // 创建登录用户对象
            return createLoginUser(user, permissions);
            
        } catch (Exception e) {
            log.error("查询用户信息异常: {}", e.getMessage(), e);
            throw new UsernameNotFoundException("用户查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 验证用户状态
     */
    private void validateUserStatus(UserDTO user) {
        if ("1".equals(user.getStatus())) {
            log.info("登录用户：{} 已被停用.", user.getUserName());
            throw new ServiceException("对不起，您的账号：" + user.getUserName() + " 已停用");
        }
        
        if ("1".equals(user.getDelFlag())) {
            log.info("登录用户：{} 已被删除.", user.getUserName());
            throw new ServiceException("对不起，您的账号：" + user.getUserName() + " 已删除");
        }
    }

    /**
     * 从UserDTO创建登录用户
     */
    private LoginUser createLoginUser(UserDTO user, Set<String> permissions) {
        // 创建LoginUser对象，包含完整的用户信息
        return new LoginUser(
            user.getUserId(),
            user.getDeptId() != null ? user.getDeptId() : 1L,
            user.getUserName(),
            user.getPassword(),
            permissions
        );
    }
    
    /**
     * 创建登录用户（兼容旧版本）
     */
    private LoginUser createLoginUser(Long userId, Long deptId, String username, String password, Set<String> permissions) {
        return new LoginUser(userId, deptId, username, password, permissions);
    }

    /**
     * 创建管理员权限集合
     */
    private Set<String> createAdminPermissions() {
        Set<String> permissions = new HashSet<>();
        permissions.add("*:*:*"); // 超级管理员权限
        return permissions;
    }

    /**
     * 创建普通用户权限集合
     */
    private Set<String> createUserPermissions() {
        Set<String> permissions = new HashSet<>();
        permissions.add("system:user:list");
        permissions.add("system:user:query");
        permissions.add("system:role:list");
        permissions.add("system:role:query");
        return permissions;
    }

    /**
     * 根据用户ID查询用户权限
     * 
     * @param userId 用户ID
     * @return 权限集合
     */
    @Cacheable(value = "user:permissions", key = "#userId", 
               condition = "#userId != null && #userId > 0")
    public Set<String> getUserPermissions(Long userId) {
        try {
            // 从数据库查询用户权限
            Set<String> permissions = userService.getUserPermissions(userId);
            
            // 如果用户权限为空，则返回基础权限
            if (permissions == null || permissions.isEmpty()) {
                permissions = createUserPermissions();
            }
            
            return permissions;
            
        } catch (Exception e) {
            log.error("查询用户权限异常: userId={}, error={}", userId, e.getMessage(), e);
            // 异常情况下返回基础权限
            return createUserPermissions();
        }
    }
}
